#include "EventLoopThread.h"
#include "EventLoop.h"

EventLoopThread::EventLoopThread(const ThreadInitCallback& cb, const std::string &name)
    : loop_(nullptr), thread_(std::bind(&EventLoopThread::threadFunc, this), name), mutex_(), cond_(), callback_(cb), exiting_(false)
{
    printf("EventLoopThread ctor called, this=%p, name=%s\n", this, name.c_str());
}

EventLoopThread::~EventLoopThread()
{
    exiting_ = true;
    if (loop_ != nullptr)
    {
        loop_->quit();
        thread_.join();
    }
}

/**
 *  startloop 和 threadfunc是muduo网络库 one loop per thread的核心机制
 *      一个线程只能有一个EventLoop
 *      一个EventLoop只能属于一个线程
 *      EventLoop只能在创建它的线程中运行
 *
 *  startLoop 的核心作用：
 *      1. 开启新线程去执行func，也就是threadFunc
 *          threadFunc执行时会使loop对象进入loop循环
 *      2. 返回loop指针 （确保返回的不是空）
 *          当thradFunc中的loop对象退出loop循环的时候，返回的loop指针同步失效
 */
EventLoop *EventLoopThread::startLoop()
{
    thread_.start(); // 启动底层新线程去 执行 func, 也就是threadFunc
    EventLoop *loop = nullptr;
    {
        std::unique_lock<std::mutex> lock(mutex_);
        while (loop_ == nullptr)
        {
            cond_.wait(lock);
        }
        loop = loop_;
    }
    return loop;
}

void EventLoopThread::threadFunc()
{
    EventLoop loop;
    if (callback_)
    {
        callback_(&loop);
    }

    {
        std::unique_lock<std::mutex> lock(mutex_);
        loop_ = &loop;
        cond_.notify_one();
    }

    loop.loop();
    std::unique_lock<std::mutex> lock(mutex_);
    loop_ = nullptr;
}
